package com.tensquare.base.service;
/*
 *ClassName:LabelService
 *Description:标签业务逻辑类,实现基本的增删改查功能
 *@author:可爱的大鸭子
 */

import com.tensquare.base.dao.LabelDao;
import com.tensquare.base.pojo.Label;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import util.IdWorker;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.swing.text.LabelView;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class LabelService {
    @Autowired
    private LabelDao labelDao;
    @Autowired
    private IdWorker idWorker;

    /**
     * 查询全部标签
     * @return
     */
    public List<Label> findAll(){
        return labelDao.findAll();
    }

    /**
     * 根据ID查询标签
     * @return
     */
    public Label findById(String id){
        return labelDao.findById(id).get();
    }

    /**
     * 增加标签
     * @param label
     */
    @Transactional
    public int add(Label label){
        label.setId( idWorker.nextId()+"" );    //设置ID
        if(labelDao.findByLabelname(label.getLabelname().toLowerCase())!=null) return 0;
        if(label.getCount()==null) label.setCount((long)0);
        if(label.getFans()==null) label.setFans((long)0);
        labelDao.save(label);
        return 1;
    }

    /**
     * 修改标签
     * @param label
     */
    @Transactional
    public int update(Label label){
        if(labelDao.findByLabelname(label.getLabelname().toLowerCase())!=null) return 0;
        labelDao.save(label);
        return 1;
    }

    /**
     * 删除标签
     * @param id
     */
    @Transactional
    public void deleteById(String id){
        labelDao.deleteById(id);
    }

    /**
     * 构建查询条件
     * @param searchMap 前端传递过来的查询条件
     * @return
     */
    private Specification<Label> createSpecification(Map searchMap){
        //Specification<Label>内部需要Predicate作为条件
        return new Specification<Label>() {
            /**
             * @param root 根对象，也就是把条件封装到的对象中去，where 类名=？
             * @param criteriaQuery 封装的都是查询关键字，比如group by order by等，用到不多
             * @param cb 用来封装条件对象的，如果直接返回null，表示不需要任何条件。
             * @return 封装好的条件作为要传递的参数
             */
            @Override
            public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                List<Predicate> predicateList=new ArrayList<>();
                if(searchMap.get("labelname")!=null && !"".equals(searchMap.get("labelname"))){
                    predicateList.add(cb.like(
                            root.get("labelname").as(String.class),         //要在那个对应的属性字段查询
                            "%"+ (String)searchMap.get("labelname")+"%" ) );//查询的值
                }
                //前端传递过来的参数不能为空才会作为合格的条件来查询
                if(searchMap.get("state")!=null && !"".equals(searchMap.get("state"))){
                    predicateList.add(cb.equal(
                            root.get("state").as(String.class),
                            (String)searchMap.get("state") ) );
                }
                if(searchMap.get("recommend")!=null && !"".equals(searchMap.get("recommend"))){
                    predicateList.add(cb.equal(
                            root.get("recommend").as(String.class),
                            (String)searchMap.get("recommend") ) );
                }
                //将list转为[]和cb做and操作返回Predicate条件对象
                return cb.and( predicateList.toArray(new Predicate[predicateList.size()]) );
            }
        };
    }
    /**
     * 条件查询
     * @param searchMap 要使用的条件
     * @return
     */
    public List<Label> findSearch(Map searchMap){
        Specification<Label> specification= createSpecification(searchMap);
        return labelDao.findAll(specification);
    }

    /**
     * 将obj对象转为map
     * @param obj
     * @return
     */
    private static Map<String, String> obj2Map(Object obj) {
        Map<String, String> map = new HashMap<>();
        // 获取f对象对应类中的所有属性域
        Field[] fields = obj.getClass().getDeclaredFields();
        for (int i = 0, len = fields.length; i < len; i++) {
            String varName = fields[i].getName();
            try {
                // 获取原来的访问控制权限
                boolean accessFlag = fields[i].isAccessible();
                // 修改访问控制权限
                fields[i].setAccessible(true);
                // 获取在对象f中属性fields[i]对应的对象中的变量
                Object o = fields[i].get(obj);
                if (o != null)
                    map.put(varName, o.toString());
                // 恢复访问控制权限
                fields[i].setAccessible(accessFlag);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }
    /**
     * 条件+分页查询
     * @param page
     * @param size
     * @param label
     * @return
     */
    public Page<Label> pageQuery(int page, int size, Label label) {
        Specification<Label> specification= createSpecification(obj2Map(label));
        PageRequest pageRequest=PageRequest.of(page-1,size);
        return labelDao.findAll(specification,pageRequest);
    }

    /**
     * 查询推荐标签列表
     * @return
     */
    public List<Label> findTopList() {
        return labelDao.findAllByRecommend("1");
    }

    /**
     * 查询有效标签列表
     * @return
     */
    public List<Label> findList() {
        return labelDao.findAllByState("1");
    }

    /*查询热门标签列表*/
    public List<Label> findhotlist() {
        return labelDao.findTop6ByCount();
    }

    //查询我关注的标签列表
    public List<String> getMyLabels(String me) {
        return labelDao.getMyLabels(me);
    }
}
